﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using EnvDTE;
using EnvDTE80;
using SPVisualDev.VSAddin.Dialogs;
using SPVisualDev.Services;

namespace SPVisualDev.VSAddin.UserControls
{
    public partial class UCToolPane : UserControl
    {
        private DTE2 m_dte;
        private Connect m_addin_instance;
        private SpecialProject m_project;
        private Window2 m_parent_window;
        private object[] m_selected_object;
        private string m_push_down_view_type;

        public UCToolPane()
        {
            InitializeComponent();

            this.ProjectExplorer.TreeView.CheckBoxes = true;
            this.ProjectExplorer.TreeView.AfterCheck += new TreeViewEventHandler(TreeView_AfterCheck);

            this.SPExplorer.ShowLists = true;
            this.SPExplorer.ShowListFolders = true;
            this.SPExplorer.ShowListItems = true;
            this.SPExplorer.DisableContextMenus = false;

            this.SPExplorer.ObjectSelected += new ObjectSelectedEventHandler(SPExplorer_ObjectSelected);

            m_push_down_view_type = "TreeView";
        }

        private void SPExplorer_ObjectSelected(IExplorerObjectContainer container, object SelectedObject)
        {
            try
            {
                if (SelectedObject == null)
                    return;

                if (SelectedObject is IDictionary<string, string>)
                {
                    this.SelectedObject = new FarmExplorerObjectWrapper(SelectedObject as IDictionary<string, string>);
                }
                else
                {
                    this.SelectedObject = SelectedObject;
                }

                m_selected_object = new object[] { this.SelectedObject };

                m_parent_window.SetSelectionContainer(ref m_selected_object);

                Window2 prop_win = m_dte.Windows.Item(Constants.vsWindowKindProperties) as Window2;
                if (prop_win != null)
                {
                    if (prop_win.Visible)
                    {
                        prop_win.Activate();
                    }
                }

            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        public object SelectedObject
        {
            get;
            set;
        }


        public void Initialize(DTE2 dte, Window2 ParentWindow, Connect addInInst)
        {
            m_dte = dte;
            m_addin_instance = addInInst;
            m_parent_window = ParentWindow;

            if (Connect.S_Client_Install)
            {
                this.btnConnectToLocalFarm.Enabled = false;
            }
        }

        internal void SetActiveProject(SpecialProject specialProject)
        {
            m_project = specialProject;

            try
            {
                if (Common.GetUserRegistryParam(SettingsPageRemote.C_PARAM_REMOTE_SERVER_USE, false) != "True")
                {
                    btnConnectGlobal.Enabled = false;
                }
                else
                {
                    btnConnectGlobal.Enabled = true;
                }

                if (specialProject != null && m_dte.Solution.Projects.Count > 0)
                {
                    this.lblProjectName.Text = specialProject.Project.Name;

                    RenderPushDownFilesView();

                    if (specialProject.UseRemoteServer)
                    {
                        this.btnConnectToCurrentProject.Enabled = true;

                        if (specialProject.IsRemoteConfigFromSolution)
                        {
                            this.btnConnectToCurrentProject.Text = "Connect using solution settings";
                        }
                        else
                        {
                            this.btnConnectToCurrentProject.Text = "Connect using project settings";
                        }
                    }
                    else
                    {
                        this.btnConnectToCurrentProject.Enabled = false;
                    }
                }
                else
                {
                    this.ProjectExplorer.TreeView.Nodes.Clear();
                    this.ProjectExplorer.TreeView.Refresh();

                    this.btnConnectToCurrentProject.Enabled = false;
                }
            }
            catch
            {
                //m_last_selected_project = null;
                throw;
            }

        }

        private void TreeView_AfterCheck(object sender, TreeViewEventArgs e)
        {
            if (e.Action == TreeViewAction.Unknown)
                return;

            try
            {
                //Test if project is still opened.
                string s = m_project.Project.UniqueName;
            }
            catch (System.Runtime.InteropServices.COMException)
            {
                this.ProjectExplorer.TreeView.Nodes.Clear();
                return;
            }

            if (e.Node.Checked == false && e.Node.Nodes.Count > 0)
            {
                string msg = "This will uncheck all sub nodes too. Do you want to continue?";
                if (MessageBox.Show(msg, "Prompt", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation, MessageBoxDefaultButton.Button2) != DialogResult.Yes)
                {
                    e.Node.Checked = true;
                    return;
                }
            }

            this.ProjectExplorer.ForEachNode(delegate(TreeNode node)
            {
                if (e.Node.Checked)
                {
                    node.Checked = true;
                    m_project.PushDown.DeletePath(node.Name, true);
                }
                else
                {
                    node.Checked = false;
                    m_project.PushDown.AddPath(node.Name, true);
                }
            }, e.Node);


            m_project.PushDown.WriteSettings();
        }

        internal void RenderPushDownFilesView()
        {
            this.ProjectExplorer.TreeView.Nodes.Clear();

            if (m_project == null)
                return;

            this.tabCustomToolPane.Show();
            Application.DoEvents();

            if (m_push_down_view_type == "TreeView")
            {
                this.ProjectExplorer.TreeView.CheckBoxes = true;
                this.ProjectExplorer.Initialize(m_project.Project);

                ProjectItem item = null;
                try
                {
                    item = m_project.Project.ProjectItems.Item("12");
                }
                catch { }

                if (item != null)
                {
                    this.ProjectExplorer.RootFolder = item;
                    this.ProjectExplorer.RenderRootNode();

                    if (this.ProjectExplorer.TreeView.TopNode != null)
                    {
                        this.ProjectExplorer.ForEachNode(delegate(TreeNode node)
                        {
                            node.Checked = !m_project.PushDown.IsPathExcluded(node.Name);

                        }, null);
                    }

                }
            }
            else
            {
                this.ProjectExplorer.TreeView.CheckBoxes = false;

                TreeNode node = new TreeNode("Excluded paths");
                node.ImageKey = "Folder";
                node.SelectedImageKey = "Folder";

                this.ProjectExplorer.TreeView.Nodes.Add(node);
                this.ProjectExplorer.TreeView.TopNode = node;

                foreach (string path in m_project.PushDown.ExcludedPaths)
                {
                    node = new TreeNode(path);
                    node.ImageKey = "Folder";
                    node.SelectedImageKey = "Folder";

                    MenuItem menuItem = new MenuItem("Remove exclusion", new EventHandler(pushDownFlatView_delete));
                    menuItem.Tag = path;

                    node.ContextMenu = new ContextMenu();
                    node.ContextMenu.MenuItems.Add(menuItem);

                    this.ProjectExplorer.TreeView.TopNode.Nodes.Add(node);
                }

                this.ProjectExplorer.TreeView.TopNode.Expand();
            }
        }

        private void pushDownFlatView_delete(object sender, EventArgs args)
        {

            try
            {
                if (MessageBox.Show("Do you want to delete thisentry?", "Prompt", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) != DialogResult.Yes)
                    return;

                MenuItem menuItem = sender as MenuItem;

                m_project.PushDown.DeletePath(menuItem.Tag.ToString(), false);
                m_project.PushDown.WriteSettings();

                RenderPushDownFilesView();

            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        internal void ShowFarmExplorerView()
        {
            this.tabPage_FarmExplorer.Show();
            Application.DoEvents();

            if (m_project != null)
            {
                bool bShow = false;
                if (m_project != this.SPExplorer.CurrentProject)
                    bShow = true;

                if (this.SPExplorer.HasContent() && this.SPExplorer.CurrentProject == null)
                    bShow = false;

                if (bShow)
                {
                    this.txtServerAdress.Text = m_project.RemoteConnection.Address;
                    this.txtServerPort.Text = m_project.RemoteConnection.Port.ToString();

                    this.SPExplorer.InitExplorer(m_dte, m_project, 0);
                }
            }
            else
            {
                if (this.SPExplorer.HasContent() && this.SPExplorer.CurrentProject == null)
                {
                    this.SPExplorer.InitExplorer(m_dte, null, 1);
                }
            }

            this.tabCustomToolPane.SelectedTab = this.tabPage_FarmExplorer;
        }

        internal void ShowPushDownView()
        {
            this.tabCustomToolPane.SelectedTab = this.tabPage_PushDownView;
            this.tabPage_PushDownView.Show();
            Application.DoEvents();
        }

        private void btnConnect_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.txtServerAdress.Text == "")
                {
                    MessageBox.Show("You must set a server address.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                this.SPExplorer.RemoteServerAddress = this.txtServerAdress.Text;

                if (string.IsNullOrEmpty(this.txtServerPort.Text))
                    this.txtServerPort.Text = Common.C_WCF_MAIN_SVC_PORT.ToString();

                this.SPExplorer.RemoteServerPort = int.Parse(this.txtServerPort.Text);
                this.SPExplorer.RemoteServerUserName = "";
                this.SPExplorer.RemoteServerPassword = "";

                try
                {
                    this.SPExplorer.RemoteServerPort = int.Parse(this.txtServerPort.Text);
                }
                catch
                {
                    MessageBox.Show("Not a valid port number. Must be an integer value between 0 - 65535.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }

                this.SPExplorer.InitExplorer(m_dte, null, 2);
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void btnConnectToCurrentProject_Click(object sender, EventArgs e)
        {
            try
            {
                SetActiveProject(m_project);

                this.txtServerAdress.Text = "";

                this.SPExplorer.RemoteServerAddress = "";                
                this.SPExplorer.InitExplorer(m_dte, m_project, 0);

                //this.txtServerAdress.Text = this.SPExplorer.RemoteServerAddress;
                //this.txtServerPort.Text = this.SPExplorer.RemoteServerPort.ToString();
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void btnConnectToLocalFarm_Click(object sender, EventArgs e)
        {
            try
            {
                this.txtServerAdress.Text = "";
                this.SPExplorer.RemoteServerAddress = "";
                this.SPExplorer.InitExplorer(m_dte, null, 2);
            }
            catch(Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void btnRefresh_Click(object sender, EventArgs e)
        {
            if (m_project != null)
            {
                RenderPushDownFilesView();
            }
        }

        private void btnConnectGlobal_Click(object sender, EventArgs e)
        {
            try
            {
                if (Common.GetUserRegistryParam(SettingsPageRemote.C_PARAM_REMOTE_SERVER_USE, false) == "True")
                {
                    this.txtServerAdress.Text = "";
                    this.SPExplorer.RemoteServerAddress = "";
                    this.SPExplorer.InitExplorer(m_dte, null, 1);
                }
                else
                {
                    MessageBox.Show("Global remote settings is not configured. Go to Visual studio options page and activate SPVisualDev remote settings.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                }
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }

        private void btnPushDownViewType_Click(object sender, EventArgs e)
        {
            try
            {
                if (this.btnPushDownViewType.Text == "Flat view")
                {
                    this.lblProjectHeading.Text = "Excluded paths for project";
                    this.btnPushDownViewType.Text = "Tree view";
                    m_push_down_view_type = "FlatView";
                }
                else
                {
                    this.lblProjectHeading.Text = "Project";
                    this.btnPushDownViewType.Text = "Flat view";
                    m_push_down_view_type = "TreeView";
                }

                RenderPushDownFilesView();
            }
            catch (Exception ex)
            {
                DialogError.ShowError(ex);
            }
        }
    }

}
